from fastapi import Request
from langchain.prompts import (
    SystemMessagePromptTemplate,
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain_openai import ChatOpenAI
from app.init_manager.init_gdb_scheme import InitGremlinGdbSchemeForPromqt


class GdbPromqtManager:

    def __init__(self, request: Request):
        self.llm = ChatOpenAI(temperature=0, verbose=True, model='gpt-4')
        self.obj = InitGremlinGdbSchemeForPromqt()
        self.request = request

    @property
    def get_promqt_string(self) -> str:
        res = self.obj.get_label_with_properties(self.obj.get_schemes_labels())
        result_string = []
        for data in res:
            result_string.append(f'label:{data.get("label")} properties:({data.get("properties")})')
        return '\n'.join(result_string)

    def build_message_from_templates(self):
        redis_gdb_cache_key = 'promqt:redis_gdb_cache_key_promqt'
        value = self.request.app.state.redis.get(redis_gdb_cache_key)
        if value:
            system_template_string = self.request.app.state.redis.get(redis_gdb_cache_key)
        else:
            system_template_string = f"""
            你是一个全新语法学习的制定者,现在提供Gremlin graph db对应的结构关系,结构关系如下:
            
            {self.get_promqt_string}
            
            严格遵循一下4点规则:
            
            1.注意完全理解表结构的关系并根据下面的问题进行处理回答用户的问题.
            接下来会提供你对应正确和错误的规则进行学习,案例如下:
            只需要返回正确例子中answer的结果即可! 结果中只需要语句!
            提供的例子中存在正则的语法，需要根据场景执行替换对应信息

            2.只返回语句，不用给出解释，不用道歉, 不用对不起，尽可能的给出想要的结果
            强调不要写超出 schema 之外的点、边类型
            尝试理解不同用户问题的相似含义, 相似含义的做相同的处理
            返回的结果不关心任何编程语言执行能力，要求通用才行，所用到的关键字需要符合查询语法,严格禁止使用以下gremlin 查询关键字 textContains, textWithout
            
            3.根据用户的问题，尝试提炼用户问题中的关键信息并给出对应你认为合理的结果,不需要你去解释和问询
            忽略与提问相关的背景信息
            你需要返回的内容一定是下面的形式,处理结果相应要求如下,不要出现任何和查询语句无关的内容和任何符号
            g.xxx
            
            4. 生成的answer中不允许出现textContains和textWithout等关键字,并把textContains替换成containing
             textWithout替换成without
            """
            self.request.app.state.redis.set(redis_gdb_cache_key, system_template_string)

        system_message_template = SystemMessagePromptTemplate.from_template(system_template_string)
        hunman_message_talk = '{question}'
        hunman_message_talk_template = HumanMessagePromptTemplate.from_template(hunman_message_talk)

        system_message_templates = [
            system_message_template,
            hunman_message_talk_template,
        ]
        chat_prompts = ChatPromptTemplate.from_messages(system_message_templates)
        return chat_prompts

    def get_chat_prompts(self):
        return self.build_message_from_templates()

    def get_chat_handler(self):
        return self.get_chat_prompts() | self.llm
